package com.platform.pdf;

import com.itextpdf.text.pdf.PdfWriter;
import com.platform.comm.exceptions.RestApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.pdf.PDFEncryption;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;

/**
 * pdf
 *
 * @author qijunyu
 */
@Slf4j
public class PdfDocumentGenerator {

    private HtmlGenerator htmlGenerator;

    public PdfDocumentGenerator(FreeMarkerConfigurer fmc) {
        htmlGenerator = new HtmlGenerator(fmc);
    }

    /**
     * 生成PDF 入口
     */
    public void generate(String template, Object variables,
                         OutputStream out) throws Exception {

        try {
            String htmlContent = htmlGenerator.generate(template,
                    variables);
            this.generate(htmlContent, out);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RestApiException(e.getMessage());
        }

    }


    /**
     * Output a pdf to the specified outputstream
     *
     * @param htmlContent the htmlstr
     */
    private void generate(String htmlContent, OutputStream out)
            throws Exception {
        ITextRenderer iTextRenderer = null;
        try {
            DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(htmlContent
                    .getBytes("UTF-8")));
            iTextRenderer = ITextRendererObjectFactory
                    .getObjectPool().borrowObject();
            try {
                iTextRenderer.setDocument(doc, null);
                iTextRenderer.layout();
                iTextRenderer.setPDFEncryption(new PDFEncryption(null, null,
                        PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_40));
                iTextRenderer.createPDF(out,true);
            } catch (Exception e) {
                ITextRendererObjectFactory.getObjectPool().invalidateObject(iTextRenderer);
                iTextRenderer = null;
            }

        } finally {
            if (out != null) {
                out.close();
            }
            if (iTextRenderer != null) {
                try {
                    resetDidValues(iTextRenderer);
                    ITextRendererObjectFactory.getObjectPool().returnObject(iTextRenderer);
                } catch (Exception ex) {
                    log.error(ex.getMessage(), ex);
                }
            }
        }
    }

    private void resetDidValues(ITextRenderer iTextRenderer) {
        ITextOutputDevice outputDevice = iTextRenderer.getOutputDevice();
        outputDevice.setMetadata("title", null);
        outputDevice.setMetadata("author", null);
        outputDevice.setMetadata("subject", null);
        outputDevice.setMetadata("keywords", null);
    }

}
